Imports Microsoft.VisualBasic
Imports System
Imports System.Windows.Forms
Imports ImapClientDemo.Security
Imports Cforge.Net
Imports Cforge.Net.Mail
Imports Cforge.Security.Certificates

Namespace ImapClientDemo
	Partial Public Class ImapClient
		Inherits Form
		''' <summary>
		''' Defines connection states.
		''' </summary>
		Private Enum ConnectionState
			NotConnected
			Connecting
			Ready
			Disconnecting
		End Enum

        Private ReadOnly _exception As Boolean ' Incidates whether a licensing exception has occurred.
        Private _messagesDelete As Boolean

		Private _settings As LoginInfo ' Login information.
		Private _state As ConnectionState ' Current connection state.

		Private _disableCount As Integer

		Private _currentFolder As String = String.Empty ' Selected folder name.

		Public Sub New()
			Try
				InitializeComponent()
			Catch exc As Exception
				If TypeOf exc Is Cforge.Licensing.Imap.SfbLicenseException OrElse TypeOf exc Is Cforge.Licensing.Mime.SfbLicenseException Then
					MessageBox.Show(exc.Message, "Error")
					_exception = True
					Return
				End If

				Throw
			End Try
		End Sub

		''' <summary>
		''' Handles the form's Load event.
		''' </summary>
		''' <param name="e">The event arguments.</param>
		Protected Overrides Sub OnLoad(ByVal e As EventArgs)
			MyBase.OnLoad(e)
			' Close the application if an exception occurred.
			If _exception Then
				Me.Close()
			End If

			' Load settings from the Registry.
			_settings = LoginInfo.LoadConfig()
		End Sub

		''' <summary>
		''' Handles the form's Closed event.
		''' </summary>
		''' <param name="e">The event arguments.</param>
		Protected Overrides Sub OnClosed(ByVal e As EventArgs)
			' Make sure to close the IMAP session before leaving.
			If loginToolStripMenuItem.Enabled AndAlso loginToolStripMenuItem.Text = "&Logout" Then
				' Close the connection.
				Disconnect()

				' Wait for the completion.
				Do While _state <> ConnectionState.NotConnected
					System.Threading.Thread.Sleep(50)
					' Wake up the GUI.
					System.Windows.Forms.Application.DoEvents()
				Loop
			End If

			' And save the settings.
			_settings.SaveConfig()

			MyBase.OnClosed(e)
		End Sub

		''' <summary>
		''' Closes the connection and release used resources.
		''' </summary>
		Private Sub Disconnect()
            ' Disable the session timeout timer.
            sessionTimeoutTimer.Enabled = False

            Try
                If _messagesDelete Then
                    _messagesDelete = False
                    SetStatusText("Applying changes...")
                    client.Purge()
                End If

                ' Set Disconnecting state.
                _state = ConnectionState.Disconnecting
                SetStatusText("Disconnecting...")

                ' Asynchronously disconnect.
                client.BeginDisconnect(False)
            Catch exc As Exception
                Util.ShowError(exc)
                SetStatusText("Ready")
            End Try
		End Sub

		''' <summary>
		''' Logins to the IMAP server.
		''' </summary>
		Private Sub Login()
			Dim par As TlsSslSecuritySettings = Nothing

			' Implicit or Explicit security mode is chosen.
            If _settings.SecurityMode <> ImapSecurityMode.Unsecure Then
                ' Initialize the Security settings.
                par = New TlsSslSecuritySettings()
                par.CommonName = _settings.Server
                par.CertificateValidator = New CustomCertValidator()

                If String.IsNullOrEmpty(_settings.Cert) Then
                    par.CertificateProvider = New CustomCertProvider()
                Else
                    ' Load Certificate.
                    Dim dlg As New PasswordPrompt()
                    ' Show passphrase form.
                    If dlg.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
                        Try
                            Dim ch As X509CertificateChain = X509CertificateChain.LoadCertificateChain(_settings.Cert, dlg.Password)
                            par.CertificateProvider = CertificateChainProviders.CreateChainProvider(ch)
                        Catch exc As Exception
                            Util.ShowError(exc)
                            Return
                        End Try
                    End If
                End If

                Dim pv As TlsSslProtocolVersionFlag = TlsSslProtocolVersionFlag.None
                If _settings.Tls Then
                    pv = TlsSslProtocolVersionFlag.TLS10
                End If
                If _settings.Ssl Then
                    pv = pv Or TlsSslProtocolVersionFlag.SSL30
                End If

                If pv <> TlsSslProtocolVersionFlag.None Then
                    par.ProtocolVersion = pv
                End If

                If _settings.Suites = 0 Then
                    par.Suites = TlsSslCipherSuite.All
                Else
                    par.Suites = TlsSslCipherSuite.Secure
                End If
            End If

			' Set timeout.
			client.Timeout = _settings.Timeout

			Dim proxy As New WebProxyEx()
			client.Proxy = proxy
			' Setup proxy.
			If _settings.ProxyServer.Length > 0 AndAlso _settings.ProxyPort > 0 Then
				proxy.Host = _settings.ProxyServer
				proxy.Port = _settings.ProxyPort
				proxy.UserName = _settings.ProxyUserName
				proxy.Password = _settings.ProxyPassword
				proxy.ProxyType = _settings.ProxyType
				proxy.AuthenticationMethod = _settings.ProxyAuthenticationMethod
			End If

			Try
				SetStatusText("Connecting to {0}:{1}...", _settings.Server, _settings.Port)
				_state = ConnectionState.Connecting
				' Disable controls.
				EnableDialog(False)
				' Connect to the IMAP server.
				client.BeginConnect(_settings.Server, _settings.Port, par, _settings.SecurityMode)
			Catch exc As Exception
				Util.ShowError(exc)
				Disconnect()
			End Try
		End Sub

		Private Sub EnableDialogImm(ByVal enable As Boolean)
			listView.Enabled = enable
			treeView.Enabled = enable
			tsMain.Enabled = enable
			treeViewContextMenuStrip.Enabled = enable
			listViewContextMenuStrip.Enabled = enable
			loginToolStripMenuItem.Enabled = enable
			exitToolStripMenuItem.Enabled = enable
			mnsMain.Enabled = enable

			Util.EnableCloseButton(Me, enable)
		End Sub

		Private Sub EnableProgress(ByVal enable As Boolean, ByVal maxValue As Integer)
			_cancelling = False
			toolStripStatusLabel.Visible = Not enable
			toolStripProgressBar.Visible = enable
			toolStripProgressBar.Value = 0
			toolStripProgressBar.Maximum = maxValue
			toolStripProgressCancelButton.Visible = enable
			toolStripProgressLabel.Text = String.Empty
			toolStripProgressLabel.Visible = enable

			EnableDialog((Not enable))
		End Sub

		Private Sub EnableDialog(ByVal enable As Boolean)
			If enable Then
				If _disableCount > 0 Then
					_disableCount -= 1
					If _disableCount = 0 Then
						EnableDialogImm(True)
						SetStatusText("Ready")
					End If
				End If
			Else
				If _disableCount = 0 Then
					EnableDialogImm(False)
				End If
				_disableCount += 1
			End If
		End Sub

		''' <summary>
		''' Sets the status text.
		''' </summary>
		''' <param name="str">The new status text.</param>
		Private Sub SetStatusText(ByVal str As String)
			toolStripStatusLabel.Text = str
		End Sub

		''' <summary>
		''' Sets the status text.
		''' </summary>
		''' <param name="str">The new status format text.</param>
		''' <param name="parameters">The parameters.</param>
		Private Sub SetStatusText(ByVal str As String, ParamArray ByVal parameters() As Object)
			toolStripStatusLabel.Text = String.Format(str, parameters)
		End Sub

		Private Sub aboutToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles aboutToolStripMenuItem.Click
            'Dim form As New AboutForm()
            'form.ShowDialog()
		End Sub

		Private Sub deleteToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles deleteToolStripMenuItem.Click
			tsbDelete_Click(sender, Nothing)
		End Sub

		Private Sub openMessageToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles openMessageToolStripMenuItem.Click
			tsbOpen_Click(sender, Nothing)
		End Sub

		Private Sub undeleteToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles undeleteToolStripMenuItem.Click
			tsbUndelete_Click(sender, Nothing)
		End Sub

		Private Sub saveMessageAsToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles saveMessageAsToolStripMenuItem.Click
			tsbSaveAs_Click(sender, e)
		End Sub

		Private Sub newMailboxToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles newMailboxToolStripMenuItem.Click
			NewFolder()
		End Sub

		Private Sub purgeToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles purgeToolStripMenuItem.Click
			PurgeMessages()
		End Sub

		Private Sub uploadLocalMessageToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles uploadLocalMessageToolStripMenuItem.Click
			UploadMessage()
		End Sub

		Private Sub renameMailboxToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles renameMailboxToolStripMenuItem.Click
			treeView.SelectedNode.BeginEdit()
		End Sub

		Private Sub deleteMaillboxToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles deleteMaillboxToolStripMenuItem.Click
			DeleteFolder()
		End Sub

		Private Sub refreshToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles refreshToolStripMenuItem.Click
			tsbRefresh_Click(sender, Nothing)
		End Sub

		Private Sub loginToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles loginToolStripMenuItem.Click
			' Is logged in?
			If loginToolStripMenuItem.Text = "&Login..." Then
				tsbLogin_Click(sender, Nothing)
			Else
				tsbLogout_Click(sender, Nothing)
			End If
		End Sub

		Private Sub exitToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles exitToolStripMenuItem.Click
			Me.Close()
		End Sub

		Private Sub toolStripProgressCancelButton_ButtonClick(ByVal sender As Object, ByVal e As EventArgs) Handles toolStripProgressCancelButton.ButtonClick
			' Abort operation.
			_cancelling = True
			client.Abort()
		End Sub

		Private Sub openContextMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles openContextMenuItem.Click
			tsbOpen_Click(sender, Nothing)
		End Sub

		Private Sub deleteContextMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles deleteContextMenuItem.Click
			tsbDelete_Click(sender, Nothing)
		End Sub

		Private Sub undeleteContextMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles undeleteContextMenuItem.Click
			tsbUndelete_Click(sender, Nothing)
		End Sub

		Private Sub saveMessageAsContextMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles saveMessageAsContextMenuItem.Click
			tsbSaveAs_Click(sender, Nothing)
		End Sub

		Private Sub newFolderContextMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles newFolderContextMenuItem.Click
			NewFolder()
		End Sub

		Private Sub deleteFolderContextMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles deleteFolderContextMenuItem.Click
			DeleteFolder()
		End Sub

		Private Sub renameContextMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles renameContextMenuItem.Click
			treeView.SelectedNode.BeginEdit()
		End Sub

		Private Sub pasteMessagesContextMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles pasteMessagesTreeViewContextMenuItem.Click
			PasteMessage(_currentFolder)
		End Sub

		Private Sub purgeDeletedMessagesContextMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles purgeDeletedMessagesContextMenuItem.Click
			PurgeMessages()
		End Sub

		Private Sub sessionTimeoutTimer_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles sessionTimeoutTimer.Tick
			Try
				' Check connection state.
				If (Not client.Locked) AndAlso _state = ConnectionState.Ready AndAlso (Not client.ConnectionState.Connected) Then
					SetDisconnectedState()
				End If
			Catch
				' Close the connection if it's is closed by the server.
				Disconnect()
			End Try
		End Sub

		Private Sub copyToolStripMenuItem1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles copyToolStripMenuItem.Click
			tsbCopy_Click(sender, Nothing)
		End Sub

		Private Sub pasteToolStripMenuItem1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles pasteToolStripMenuItem.Click
			tsbPaste_Click(sender, Nothing)
		End Sub

		Private Sub copyToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles copyContextMenuItem.Click
			tsbCopy_Click(sender, Nothing)
		End Sub

		Private Sub pasteToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles pasteContextMenuItem.Click
			tsbPaste_Click(sender, Nothing)
		End Sub

		Private Sub tsbCopy_Click(ByVal sender As Object, ByVal e As EventArgs) Handles tsbCopy.Click
			CopyMessage()
		End Sub

		Private Sub tsbPaste_Click(ByVal sender As Object, ByVal e As EventArgs) Handles tsbPaste.Click
			PasteMessage(_currentFolder)
		End Sub

		Private Sub uploadLocalMessagesContextMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles uploadLocalMessagesContextMenuItem.Click
			UploadMessage()
		End Sub

		Private Sub uploadMessageToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles uploadMessageToolStripMenuItem.Click
			UploadMessage()
		End Sub

		Private Sub tsbUpload_Click(ByVal sender As Object, ByVal e As EventArgs) Handles tsbUpload.Click
			UploadMessage()
		End Sub

    End Class
    
End Namespace